package pa165.dominatingspecies.dao.impl;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.springframework.stereotype.Repository;
import pa165.dominating.species.dao.EnvironmentDao;
import pa165.dominating.species.entities.Environment;
import pa165.dominating.species.exceptions.EntityException;

/**
 *
 * @author Stanislau Dubrouski
 */
@Repository
public class EnvironmentDaoImpl implements EnvironmentDao {

    private EntityManagerFactory emf;


    private EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public EntityManagerFactory getEmf() {
        return emf;
    }

    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }

    @Override
    public void createEnvironment(Environment env) {
        EntityManager em = getEntityManager();
        this.validateEntity(env);
        if (env.getId() != null) {
            throw new EntityException("Element with id " + env.getId() + " already exist in DB.");
        }
        try {

            em.getTransaction().begin();
            em.persist(env);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    @Override
    public void deleteEnvironment(Environment env) {
        EntityManager em = getEntityManager();
        if (env.getId() == null) {
            throw new EntityException("Environment " + env + " is not in DB - id is null.");
        }
        try {
            em.getTransaction().begin();
            Environment found = em.find(Environment.class, env.getId());
            em.remove(found);
            em.getTransaction().commit();
        } finally {
            if (em.isOpen()) {
                em.close();
            }
        }
    }

    @Override
    public Environment getEnvironmentById(Long id) {
        EntityManager em = getEntityManager();
        if (id == null) {
            throw new IllegalArgumentException("id is null");
        }
        Environment env;
        try {
            em.getTransaction().begin();
            env = em.find(Environment.class, id);
            em.getTransaction().commit();
        } finally {
            if (em.isOpen()) {
                em.close();
            }
        }
        return env;
    }

    @Override
    public void updateEnvironment(Environment env) {
        EntityManager em = this.getEntityManager();
        validateEntity(env);
        try {
            em.getTransaction().begin();
            Environment found = em.find(Environment.class, env.getId());
            found.setDescription(env.getDescription());
            found.setName(env.getName());
            found.setElements(env.getElements());
            em.getTransaction().commit();
        } finally {
            if (em.isOpen()) {
                em.close();
            }
        }
    }

    @Override
    public List<Environment> getAllEnvironments() {
        EntityManager em = getEntityManager();
        List<Environment> found;
        try {
            em.getTransaction().begin();
            found = em.createNamedQuery("getAllEnvironments").getResultList();
            em.getTransaction().commit();
        } finally {
            if (em.isOpen()) {
                em.close();
            }
        }
        return found;
    }

    protected void validateEntity(Environment env) {
        if (env == null) {
            throw new EntityException("Environment is null");
        }
        if (env.getName() == null) {
            throw new EntityException("Environment name is null");
        }
        if (env.getDescription() == null) {
            throw new EntityException("Environment description is null");
        }
    }
}
